package edu.pku.sei.mte.runtime;

import java.util.HashMap;
import java.util.Map;

import edu.pku.sei.mte.exceptions.handler.MTExceptionHandler;
import edu.pku.sei.mte.modification.ModelModificationManager;
import edu.pku.sei.mte.mtemodel.model.MModelGraph;
import edu.pku.sei.mte.mtemodel.mtmodel.ModelType;
import edu.pku.sei.mte.mtemodel.mtmodel.Transformation;
import edu.pku.sei.mte.runtime.rulebased.RBTContext;
import edu.pku.sei.mte.transformation.ModelTransformationVisitor;

abstract public class Environment {

	private Map<ModelType,MModelGraph> modelCollection;
	private ModelType target;
	private Transformation transformation;
	protected Context globalContext;
	private Map<Object,Object> extraData;
	private MTExceptionHandler exhandler = new MTExceptionHandler();
	private ModelTransformationVisitor mtVisitor;
	private ModelModificationManager manager = new ModelModificationManager();

	public Environment() {
		super();
	}
	
	public Environment(Environment env) {
		modelCollection = env.modelCollection;
	}

	public Map<ModelType, MModelGraph> getModelCollection() {
		if(modelCollection==null){
			modelCollection = new HashMap<ModelType,MModelGraph>();
		}
		return modelCollection;
	}

	public ModelModificationManager getModelModificationManager(){
		return manager;
	}
	
	public ModelType getTarget() {
		return target;
	}

	public void setTarget(ModelType target) {
		this.target = target;
	}

	public boolean isTargetModel(MModelGraph model){
		return getModelCollection().get(getTarget()) == model;
	}
	
	public MModelGraph getModelGraph(ModelType  type) {
		return getModelCollection().get(type);
	}

	public Context getGlobalContext() {
		if(globalContext==null){
			globalContext = new RBTContext();
		}
		return globalContext;
	}
	
	public Context createNewContext() {
		return (Context) getGlobalContext().clone();
	}

	public Transformation getTransformation() {
		return transformation;
	}

	public void setTransformation(Transformation transformation) {
		this.transformation = transformation;
	}

	public void putExtraData(Object key,Object data){
		if(extraData==null){
			extraData = new HashMap<Object,Object>();
		}
		
		extraData.put(key, data);
	}
	public Object getExtraData(Object key){
		if(extraData==null)
			return null;
		return extraData.get(key);
	}


	public MTExceptionHandler getExhandler() {
		return exhandler;
	}

	public void setExhandler(MTExceptionHandler exhandler) {
		this.exhandler = exhandler;
	}

	public ModelTransformationVisitor getMtVisitor() {
		return mtVisitor;
	}

	public void setMtVisitor(ModelTransformationVisitor mtVisitor) {
		this.mtVisitor = mtVisitor;
	}
}